#-*- coding: UTF-8 -*-
from pyramid.httpexceptions import HTTPFound
from pyramid.security import remember
from pyramid.security import forget

from sqlalchemy.orm import eagerload


from scp.modelo.models import DBSession
from scp.modelo.Tipo_Item import Tipo_Item
from scp.modelo.Rol import Rol
from scp.modelo.Permiso import Permiso
from scp.modelo.Item import Item
from scp.modelo.Fase import Fase
from scp.modelo.ValoresCadena import ValoresCadena
from scp.modelo.ValoresNumerico import ValoresNumerico
from scp.modelo.RelacionA_S import RelacionA_S
from scp.modelo.RelacionP_H import RelacionP_H
from scp.modelo.Usuario import Usuario
from scp.modelo.Recurso import Recurso
from scp.modelo.AsignacionRecurso import AsignacionRecurso
from scp.modelo.Linea_Base import Linea_Base

from scp.modelo.ValoresFecha import ValoresFecha
from scp.modelo.ValoresArchivo import ValoresArchivo
from pyramid.response import Response
from pyramid.view import view_config
import json

import re

import pydot
import time
import sys, os
from pyramid.security import authenticated_userid

#@view_config(renderer='json')
def items(request):
	"""Método controlador encargado de la administración de los itmes.
		URL asociada: /items/{operacion}
		operacion:
			viewTipoItems: retorna tipos de items asocidos a la fase
			traerAtributos: retorna los atributos de un determinado tipo de item
		@param request: Petición Http del cliente. 	
	"""
	
	methodRequest = request.method
		
	dicParametros = request.matchdict
	

	if dicParametros.get('operacion') == 'crear' and request.url.find('?') == -1:
		print 'respondí un diccionario normal'
		return {'content':'Hello!'}	
	
	
	session = DBSession()
	if dicParametros.get('operacion') == 'viewTipoItems':
		#debemos enviar todos los tipos de items correspondientes a la fase.
		fase = session.query(Fase).filter_by(id = request.params['idFase']).first()
		#tiposItems = session.query(Tipo_Item).all()
		tiposItems = fase.tipos_items
		tiposItemsArray = []
		
		for tipoItem in tiposItems:
			aux = {'idTipoItem': tipoItem.id, 'nombreTipoItem': tipoItem.nombre} 
			tiposItemsArray.append(aux)
		
		responseView = Response()
		#responseView.body = json.dumps(dict(success = True, tiposItems = [{'idTipoItem':'1', 'nombreTipoItem': 'Caso de Uso'}, {'idTipoItem':'2', 'nombreTipoItem': 'Requerimiento Funcional'}]))
		responseView.body = json.dumps(dict(success = True, tiposItems = tiposItemsArray))
		responseView.content_type = 'application/json'
		print 'respondí con un Responseeeee!!!'
		return responseView
	
	
	if dicParametros.get('operacion') == 'traerAtributos':
		#traemos los atributos del tipo de item solicitado
		tipoItem = session.query(Tipo_Item).filter_by(id=request.params['idTipoItem']).first()
		
		atributos = tipoItem.atributos
		atributosArray = []
		
		for atributo in atributos:
			aux = {'nombre':atributo.nombre, 'tipo': atributo.tipo_dato}
			atributosArray.append(aux)
		
		responseView = Response()
		responseView.body = json.dumps(dict(success = True, atributos = atributosArray))
		responseView.content_type = 'application/json'
		print 'respondí con un Responseeeee!!!'
		return responseView
		
		
	if dicParametros.get('operacion') == 'traerItems':
		itemsFase = session.query(Item).filter_by(fase_id=request.params['idFase'], flagUltimo = 1, flagBorrado = 0).order_by('codigo').all()
		
		print ">>>cantidad de item que vamos a enviar desde el contralador"
		print len(itemsFase)
		
		usuarioLogeado = session.query(Usuario).filter_by( username = authenticated_userid(request) ).first()

		mostrarTabRelacion = puedeTabRelaciones(usuarioLogeado, request.params['idFase'])
		
		itemsJson = []
		for item in itemsFase:
			modificarItem = None
			revisarItem = None
			if item.flagRevisar == 1:
				revisarItem = 'SI'
			else:
				revisarItem = 'NO'	
			
			
			if item.flagModificar == 1:
				modificarItem = 'SI'
			else:	
				modificarItem = 'NO'
				
			aux = {'nombreItem': item.nombre, 'idItem':item.id, 'codItem': item.codigo, 'complejidadItem': item.complejidad, 
			'descripcionItem':item.descripcion , 'nombreTipoItem':item.tipoItem.nombre, 'versionItem':item.version, 'idTipoItem': item.tipoItem.id,
			'estadoItem':item.estado, 'modificarItem': modificarItem, 'revisarItem': revisarItem, 'mostrarTabRelacion':mostrarTabRelacion}
			
			itemsJson.append(aux)
		
		
		responseView = Response()
		responseView.body = json.dumps(dict(success = True, items = itemsJson))
		responseView.content_type = 'application/json'
		return responseView	
		
	if dicParametros.get('operacion') == 'guardar':
		
		itemDic = json.loads(request.params['item'])
		
		itemData = itemDic.get('data')
		
		nuevoItem = Item()
		
		#ahora vamos a calcular el codigo para el item
		nombreProyecto = request.params['nombreProyecto']
		nombreFase = request.params['nombreFase']
		
		#traemos el tipo de item
		tipoItem = session.query(Tipo_Item).filter_by(id = itemData.get('idTipoItem') ).first()
		nombreTipoItem = tipoItem.nombre
		itemsPorTipoItem = session.query(Item).filter_by(tipoItem_id = itemData.get('idTipoItem'), flagUltimo = 1 , fase_id = request.params['idFase'] ).all()
		
		secuencia = len(itemsPorTipoItem) + 1
	
		nuevoItem.codigo = nombreProyecto[0:3] + '_' + nombreFase[0:3] + '_' + nombreTipoItem[0:3] + '_' + str(secuencia)
		nuevoItem.nombre = itemData.get('nombreItem')
		nuevoItem.complejidad = itemData.get('complejidadItem')
		nuevoItem.descripcion = itemData.get('descripcionItem')
		nuevoItem.version = 1
		nuevoItem.flagUltimo = 1
		nuevoItem.flagBorrado = 0
		nuevoItem.estado = 'ACTIVO'
		
		#seteamos los flags par modificación y revisación
		nuevoItem.flagModificar = 0
		nuevoItem.flagRevisar = 0
				
		nuevoItem.tipoItem = tipoItem
		session.add( nuevoItem )
		
		#asignamos el item a la fase correspondiente
		fase = session.query(Fase).filter_by(id = request.params['idFase'] ).first()
		fase.items.append(nuevoItem)
		
		#guardamos los valores del Tipo de Item asociados al Item
		camposJson =  json.loads(request.params['camposEspecificos'])  
	
		for campo in camposJson:
			
			tipoCampo = campo.get('tipo')
			
			if tipoCampo == 'CADENA':
				valorCadenaAdd = ValoresCadena()
				valorCadenaAdd.valor = campo.get('valor')
				valorCadenaAdd.item_id = nuevoItem.id
				valorCadenaAdd.version_item = 1
				valorCadenaAdd.nombreAtributo = campo.get('nombreCampo')
				session.add(valorCadenaAdd)
			if tipoCampo == 'FECHA':
				valorFechaAdd = ValoresFecha()
				valorFechaAdd.valor = campo.get('valor')
				valorFechaAdd.item_id = nuevoItem.id
				valorFechaAdd.version_item = 1
				valorFechaAdd.nombreAtributo = campo.get('nombreCampo')
				session.add(valorFechaAdd)	
			if tipoCampo == 'NUMERICO':
				valorNumericoAdd = ValoresNumerico()
				valorNumericoAdd.valor = campo.get('valor')
				valorNumericoAdd.item_id = nuevoItem.id
				valorNumericoAdd.version_item = 1
				valorNumericoAdd.nombreAtributo = campo.get('nombreCampo')
				session.add(valorNumericoAdd)
			if tipoCampo == 'ARCHIVO':				
				archivoBD = ValoresArchivo()
				archivoBD.nombreAtributo = campo.get('nombreCampo')
				archivoBD.nombreArchivo = request.params[campo.get('nombreCampo')].filename
				archivoBD.valor = request.params[campo.get('nombreCampo')].file.read()
				archivoBD.item_id = nuevoItem.id
				archivoBD.version_item = 1
				session.add(archivoBD)
							
		
		session.add( nuevoItem )
		
		responseGuardar = Response()
		responseGuardar.body = json.dumps(dict(success = True))
		responseGuardar.content_type = 'text/html'
		
		return responseGuardar	
	
	if dicParametros.get('operacion') == 'traerAtributosValor':
		#traemos los atributos del tipo de item solicitado
		
		tipoItem = session.query(Tipo_Item).filter_by(id=request.params['idTipoItem']).first()
		
		atributos = tipoItem.atributos
		atributosArray = []
		
		for atributo in atributos:
			valor = None
			if atributo.tipo_dato == 'CADENA':
				registroValor = session.query(ValoresCadena).filter_by(item_id = request.params['idItem'], 
					nombreAtributo = atributo.nombre, version_item = request.params['versionItem']).first()
			if atributo.tipo_dato == 'FECHA':
				registroValor = session.query(ValoresFecha).filter_by(item_id = request.params['idItem'], 
					nombreAtributo = atributo.nombre, version_item = request.params['versionItem']).first()
			if atributo.tipo_dato == 'NUMERICO':
				registroValor = session.query(ValoresNumerico).filter_by(item_id = request.params['idItem'], 
					nombreAtributo = atributo.nombre, version_item = request.params['versionItem']).first()
			if atributo.tipo_dato == 'ARCHIVO':
				registroValor = session.query(ValoresArchivo).filter_by(item_id = request.params['idItem'], 
					nombreAtributo = atributo.nombre, version_item = request.params['versionItem']).first()		
			
			if atributo.tipo_dato == 'ARCHIVO':
				valor = registroValor.nombreArchivo
			else:
				valor = registroValor.valor
			
			aux = {'nombre':atributo.nombre, 'tipo': atributo.tipo_dato, 'valor': valor}
			atributosArray.append(aux)
		
		responseView = Response()
		responseView.body = json.dumps(dict(success = True, atributos = atributosArray))
		responseView.content_type = 'application/json'
		return responseView
		
	if dicParametros.get('operacion') == 'guardarEdicion':	
		
		print '>>>request en guardarEdicion'
		print request.params
		print '>>>request en guardarEdicion'
		itemDic = json.loads(request.params['item'])
		
		itemData = itemDic.get('data')
		
		nuevoItem = Item()
		itemEditado = session.query(Item).filter_by(id=request.params['idItem']).first()
		itemEditado.flagUltimo = 0
		

		nombreProyecto = request.params['nombreProyecto']
		nombreFase = request.params['nombreFase']
		
		#traemos el tipo de item
		tipoItem = session.query(Tipo_Item).filter_by(id = itemData.get('idTipoItem') ).first()
		nombreTipoItem = tipoItem.nombre
	
	
		nuevoItem.codigo = itemEditado.codigo
		nuevoItem.nombre = itemEditado.nombre
		nuevoItem.complejidad = itemData.get('complejidadItem')
		nuevoItem.descripcion = itemData.get('descripcionItem')
		nuevoItem.version = itemEditado.version + 1
		nuevoItem.flagUltimo = 1
		nuevoItem.estado = 'ACTIVO'
		nuevoItem.flagBorrado = 0
		
		#seteamos los flagas para modificación y revisición
		nuevoItem.flagRevisar = 0
		nuevoItem.flagModificar = 0
		
		
		
		nuevoItem.tipoItem = tipoItem
		
		
		session.add( nuevoItem )
		
		#asignamos el item a la fase correspondiente
		fase = session.query(Fase).filter_by(id = request.params['idFase'] ).first()
		fase.items.append(nuevoItem)
		
		#guardamos los valores del Tipo de Item asociados al Item
		camposJson =  json.loads(request.params['camposEspecificos'])  
		
		for campo in camposJson:
			
			tipoCampo = campo.get('tipo')
			
			if tipoCampo == 'CADENA':
				valorCadenaAdd = ValoresCadena()
				valorCadenaAdd.valor = campo.get('valor')
				valorCadenaAdd.item_id = nuevoItem.id
				valorCadenaAdd.version_item = nuevoItem.version
				valorCadenaAdd.nombreAtributo = campo.get('nombreCampo')
				session.add(valorCadenaAdd)
			if tipoCampo == 'FECHA':
				valorFechaAdd = ValoresFecha()
				valorFechaAdd.valor = campo.get('valor')
				valorFechaAdd.item_id = nuevoItem.id
				valorFechaAdd.version_item = nuevoItem.version
				valorFechaAdd.nombreAtributo = campo.get('nombreCampo')
				session.add(valorFechaAdd)	
			if tipoCampo == 'NUMERICO':
				valorNumericoAdd = ValoresNumerico()
				valorNumericoAdd.valor = campo.get('valor')
				valorNumericoAdd.item_id = nuevoItem.id
				valorNumericoAdd.version_item = nuevoItem.version
				valorNumericoAdd.nombreAtributo = campo.get('nombreCampo')
				session.add(valorNumericoAdd)
			if tipoCampo == 'ARCHIVO':
			
				if  not isinstance(request.params[campo.get('nombreCampo')], (str, unicode)):								
					archivoBD = ValoresArchivo()
					archivoBD.nombreAtributo = campo.get('nombreCampo')
					archivoBD.nombreArchivo = filename = request.params[campo.get('nombreCampo')].filename
					archivoBD.valor = request.params[campo.get('nombreCampo')].file.read()
					archivoBD.item_id = nuevoItem.id
					archivoBD.version_item = nuevoItem.version
					session.add(archivoBD)
				else:
					#guardamos el archivo anterior no mas
					archivoViejo = DBSession.query(ValoresArchivo).filter_by(item_id=itemEditado.id, nombreAtributo = campo.get('nombreCampo'), version_item = itemEditado.version).one()	
					archivoBD = ValoresArchivo()
					archivoBD.nombreAtributo = archivoViejo.nombreAtributo
					archivoBD.nombreArchivo = archivoViejo.nombreArchivo
					archivoBD.valor = archivoViejo.valor
					archivoBD.item_id = nuevoItem.id
					archivoBD.version_item = nuevoItem.version
					session.add(archivoBD)
					
	
		#una vez que hemos editado el item, marcamos todos los demás items dependientes para su revisión
		marcar_item_to_revision(request.params['idItem'])
	
		#reproduciomos las relaciones del item
		reproducir_relaciones_al_editar(request.params['idItem'], nuevoItem.id)
	
		responseEdit = Response()
		#responseView.body = json.dumps(dict(success = True, atributos = [{'nombre':'Nombre', 'tipo': 'Cadena'}, {'nombre':'Fecha Inicio', 'tipo': 'Fecha'}]))
		responseEdit.body = json.dumps(dict(success = True))
		responseEdit.content_type = 'text/html'

		return responseEdit
		
	if dicParametros.get('operacion') == 'eliminar':
		idItem = request.params['idItem']
		
		itemBorrar = session.query(Item).filter_by(id = idItem ).first()
		
		itemBorrar.flagBorrado = 1
		
		response = Response()
		response.body = json.dumps(dict(success = True))
		response.content_type = 'application/json'
		
		return response
	
	if dicParametros.get('operacion') == 'confirmar':
		idItem = request.params['idItem']
	
		itemConfirmar = session.query(Item).filter_by(id = idItem ).first()
	
		itemConfirmar.estado = 'PENDIENTE_APROBACION'

		#seteamos el flag de modificación a false
		itemConfirmar.flagModificar = 0
		
		
		response = Response()
		response.body = json.dumps(dict(success = True))
		response.content_type = 'application/json'
		
		return response
		
	if dicParametros.get('operacion') == 'aprobar':
		idItem = request.params['idItem']
		itemAprobado = session.query(Item).filter_by(id = idItem ).first()
		padres = session.query(RelacionP_H).filter_by(hijo = idItem).all()
		
		fase = session.query(Fase).filter_by(id = itemAprobado.fase_id).first()
		respuesta = 'ER'
		tienePadre = False
		if fase.orden > 1:
			
			for padre in padres:
				itemPadre = session.query(Item).filter_by(id = padre.padre).first()
				if itemPadre.flagBorrado == 0 and itemPadre.flagUltimo == 1:
					tienePadre = True
					if itemPadre.estado == 'APROBADO' or itemPadre.estado == 'BLOQUEADO':
						respuesta = 'OK'
						itemAprobado.estado = 'APROBADO'	
						break
						
			if respuesta == 'ER':
				if not tienePadre:
					antecesores = session.query(RelacionA_S).filter_by(sucesor = idItem).all()
					for antecesor in antecesores:
						itemAntecesor = session.query(Item).filter_by(id = antecesor.antecesor).first()
						if itemAntecesor.flagBorrado == 0 and itemAntecesor.flagUltimo == 1:
							respuesta = 'OK'
							itemAprobado.estado = 'APROBADO'	
							break
		
		else:
			for padre in padres:
				itemPadre = session.query(Item).filter_by(id = padre.padre).first()
				if itemPadre.flagBorrado == 0 and itemPadre.flagUltimo == 1:
					tienePadre = True
					if itemPadre.estado == 'APROBADO' or itemPadre.estado == 'BLOQUEADO':
						respuesta = 'OK'
						itemAprobado.estado = 'APROBADO'	
						break
						
			if not tienePadre:
				respuesta = 'OK'
				itemAprobado.estado = 'APROBADO'
			
			
		
		response = Response()
		response.body = json.dumps(dict(success = True, respuesta = respuesta))
		response.content_type = 'application/json'
		
		return response
	
	if dicParametros.get('operacion') == 'rechazar':
		idItem = request.params['idItem']
	
		#traemos todos sus hijos
		tieneHijos = False
		respuesta = 'OK'
		relacionesHijos = session.query(RelacionP_H).filter_by(padre = idItem).all()
		for relacionHijo in relacionesHijos:
			itemHijo = session.query(Item).filter_by(id = relacionHijo.hijo).one()
			if itemHijo.flagBorrado == 0 and itemHijo.flagUltimo == 1 and itemHijo.estado == 'APROBADO':
				tieneHijos = True
				respuesta = 'ER'
				break
				
		if not tieneHijos:		
			item = session.query(Item).filter_by(id = idItem ).first()
			item.estado = 'ACTIVO'
			mensaje = 'Operación exitosa!'
		else:
			mensaje = 'Error, el item posee al menos un hijo Aprobado'
	
	
			
		response = Response()
		response.body = json.dumps(dict(success = True, respuesta = respuesta, mensaje = mensaje))
		response.content_type = 'application/json'
		
		return response		
	
	if dicParametros.get('operacion') == 'traerHistorialItem':
		itemsFase = session.query(Item).filter_by(fase_id=request.params['idFase'], flagUltimo = 0, flagBorrado = 0, codigo = request.params['codItem']).order_by('version').all()
		
		itemsJson = []
		for item in itemsFase:
			revisarItem = None
			if item.flagRevisar == 1:
				revisarItem = True
			else:
				revisarItem = False	
			
			modificarItem = None
			if item.flagModificar == 1:
				modificarItem = True
			else:
				modificarItem = False
			
			aux = {'nombreItem': item.nombre, 'idItem':item.id, 'codItem': item.codigo, 'complejidadItem': item.complejidad, 
			'descripcionItem':item.descripcion , 'nombreTipoItem':item.tipoItem.nombre, 'versionItem':item.version, 'idTipoItem': item.tipoItem.id,
			'estadoItem':item.estado, 'revisarItem':revisarItem , 'modificarItem':modificarItem}	
			itemsJson.append(aux)
		
		
		responseView = Response()
		responseView.body = json.dumps(dict(success = True, items = itemsJson))
		responseView.content_type = 'application/json'
		return responseView
		
	if dicParametros.get('operacion') == 'revertir':	
		itemVersion = session.query(Item).filter_by(id=request.params['idItemVersion']).first() 		
		itemUltimo = session.query(Item).filter_by(id=request.params['idItemUltimo']).first()

		#comenzamos la reversión
		nuevoItem = Item()

		nuevoItem.codigo = itemVersion.codigo
		nuevoItem.nombre = itemVersion.nombre
		nuevoItem.descripcion = itemVersion.descripcion
		nuevoItem.version = itemUltimo.version + 1
		nuevoItem.flagUltimo = 1
		nuevoItem.flagBorrado = 0
		nuevoItem.estado = itemVersion.estado
		nuevoItem.complejidad = itemVersion.complejidad
		nuevoItem.tipoItem = itemVersion.tipoItem

		#asignamos el item a la fase correspondiente
		fase = session.query(Fase).filter_by(id = itemUltimo.fase_id ).first()
		fase.items.append(nuevoItem)
		
		#guardamos el item
		session.add(nuevoItem)
		
		#hacemos que la ultima version ya no sea la ultima
		itemUltimo.flagUltimo = 0
		
		
		#setemos los valores de atributo
		atributosCadena = session.query(ValoresCadena).filter_by(item_id=itemVersion.id).all() 	
		atributosFecha = session.query(ValoresFecha).filter_by(item_id=itemVersion.id).all()
		atributosNumerico = session.query(ValoresNumerico).filter_by(item_id=itemVersion.id).all()
		atributosArchivo = session.query(ValoresArchivo).filter_by(item_id=itemVersion.id).all()
		
		#vamos reversionando los atributos
		if len(atributosCadena) > 0: 
			for atributo in atributosCadena:
				nuevoAtributo = ValoresCadena()	
				nuevoAtributo.nombreAtributo = atributo.nombreAtributo
				nuevoAtributo.valor = atributo.valor
				nuevoAtributo.item_id = nuevoItem.id
				nuevoAtributo.version_item = nuevoItem.version
				session.add(nuevoAtributo)
			
				
		if len(atributosFecha) > 0:
			for atributo in atributosFecha:
				nuevoAtributo = ValoresFecha()	
				nuevoAtributo.nombreAtributo = atributo.nombreAtributo
				nuevoAtributo.valor = atributo.valor
				nuevoAtributo.item_id = nuevoItem.id
				nuevoAtributo.version_item = nuevoItem.version
				session.add(nuevoAtributo)
			
		
		
		if len(atributosNumerico) > 0:		
			for atributo in atributosNumerico:
				nuevoAtributo = ValoresNumerico()	
				nuevoAtributo.nombreAtributo = atributo.nombreAtributo
				nuevoAtributo.valor = atributo.valor
				nuevoAtributo.item_id = nuevoItem.id
				nuevoAtributo.version_item = nuevoItem.version		
				session.add(nuevoAtributo)
				
		if len(atributosArchivo) > 0:		
			for atributo in atributosArchivo:
				nuevoAtributo = ValoresArchivo()	
				nuevoAtributo.nombreAtributo = atributo.nombreAtributo
				nuevoAtributo.valor = atributo.valor
				nuevoAtributo.item_id = nuevoItem.id
				nuevoAtributo.version_item = nuevoItem.version
				nuevoAtributo.nombreArchivo = atributo.nombreArchivo		
				session.add(nuevoAtributo)
				
			
		#marcamos para la revisión los items afectados
		marcar_item_to_revision(itemUltimo.id)
		
		#reproducimos las relaciones de la versión a la cual estamos volviendo
		reproducir_relaciones_al_revertir(itemVersion.id, nuevoItem.id)
		
		#retornamos
		response = Response()
		response.body = json.dumps(dict(success = True))
		response.content_type = 'application/json'
		
		return response		
			
	if dicParametros.get('operacion') == 'traerListaRevivir':
		itemsFase = session.query(Item).filter_by(fase_id=request.params['idFase'], flagUltimo = 1, flagBorrado = 1).all()
	
			
		itemsJson = []
		for item in itemsFase:
			revisarItem = None
			if item.flagRevisar == 1:
				revisarItem = True
			else:
				revisarItem = False	
			
			modificarItem = None
			if item.flagModificar == 1:
				modificarItem = True
			else:
				modificarItem = False
			
			aux = {'nombreItem': item.nombre, 'idItem':item.id, 'codItem': item.codigo, 'complejidadItem': item.complejidad, 
			'descripcionItem':item.descripcion , 'nombreTipoItem':item.tipoItem.nombre, 'versionItem':item.version, 'idTipoItem': item.tipoItem.id,
			'estadoItem':item.estado, 'revisarItem':revisarItem , 'modificarItem':modificarItem}	
			itemsJson.append(aux)
		
		
		responseView = Response()
		responseView.body = json.dumps(dict(success = True, items = itemsJson))
		responseView.content_type = 'application/json'
		return responseView			
		
	if dicParametros.get('operacion') == 'revivir':	
		itemRevivir = session.query(Item).filter_by(id=request.params['idItemRevivir']).first()	

		itemRevivir.flagBorrado = 0
		itemRevivir.flagUltimo = 0
		
		#el revivir es internamente como una reversion, por eso es igual el codigo
		itemVersion = itemRevivir		
		itemUltimo = itemRevivir

		#comenzamos la reversión
		nuevoItem = Item()

		nuevoItem.codigo = itemVersion.codigo
		nuevoItem.nombre = itemVersion.nombre
		nuevoItem.descripcion = itemVersion.descripcion
		nuevoItem.version = itemUltimo.version + 1
		nuevoItem.flagUltimo = 1
		nuevoItem.flagBorrado = 0
		nuevoItem.estado = itemVersion.estado
		nuevoItem.complejidad = itemVersion.complejidad
		nuevoItem.tipoItem = itemVersion.tipoItem

		#asignamos el item a la fase correspondiente
		fase = session.query(Fase).filter_by(id = itemUltimo.fase_id ).first()
		fase.items.append(nuevoItem)
		
		#guardamos el item
		session.add(nuevoItem)
		
		#hacemos que la ultima version ya no sea la ultima
		itemUltimo.flagUltimo = 0
		
		
		#setemos los valores de atributo
		atributosCadena = session.query(ValoresCadena).filter_by(item_id=itemVersion.id).all() 	
		atributosFecha = session.query(ValoresFecha).filter_by(item_id=itemVersion.id).all()
		atributosNumerico = session.query(ValoresNumerico).filter_by(item_id=itemVersion.id).all()
		atributosArchivo = session.query(ValoresArchivo).filter_by(item_id=itemVersion.id).all()

		#vamos reversionando los atributos
		if len(atributosCadena) > 0: 
			for atributo in atributosCadena:
				nuevoAtributo = ValoresCadena()
				nuevoAtributo.nombreAtributo = atributo.nombreAtributo
				nuevoAtributo.valor = atributo.valor
				nuevoAtributo.item_id = nuevoItem.id
				nuevoAtributo.version_item = nuevoItem.version
				session.add(nuevoAtributo)
			
			
				
		if len(atributosFecha) > 0:	
			for atributo in atributosFecha:
				nuevoAtributo = ValoresFecha()
				nuevoAtributo.nombreAtributo = atributo.nombreAtributo
				nuevoAtributo.valor = atributo.valor
				nuevoAtributo.item_id = nuevoItem.id
				nuevoAtributo.version_item = nuevoItem.version
				session.add(nuevoAtributo)
			
		
		if len(atributosNumerico) > 0:		
			for atributo in atributosNumerico:
				nuevoAtributo = ValoresNumerico()
				nuevoAtributo.nombreAtributo = atributo.nombreAtributo
				nuevoAtributo.valor = atributo.valor
				nuevoAtributo.item_id = nuevoItem.id
				nuevoAtributo.version_item = nuevoItem.version		
				session.add(nuevoAtributo)
		
		if len(atributosArchivo) > 0:			
			for atributo in atributosArchivo:
				nuevoAtributo = ValoresArchivo()
				nuevoAtributo.nombreAtributo = atributo.nombreAtributo
				nuevoAtributo.valor = atributo.valor
				nuevoAtributo.item_id = nuevoItem.id
				nuevoAtributo.version_item = nuevoItem.version
				nuevoAtributo.nombreArchivo = atributo.nombreArchivo		
				session.add(nuevoAtributo)
			
		
		#marcamos para la revisión los items afectados
		marcar_item_to_revision(itemUltimo.id)
		
		#reproducimos las relaciones de la versión a la cual estamos volviendo
		reproducir_relaciones_al_revertir(itemVersion.id, nuevoItem.id)
		
		
		
		
		responseView = Response()
		responseView.body = json.dumps(dict(success = True))
		responseView.content_type = 'application/json'
		return responseView
	
	if dicParametros.get('operacion') == 'impactoAtras':	
		
		#necesitamos traer todas las fases ordenadas por orden
		itemSeleccionado = DBSession.query(Item).filter_by(id = request.params['idItem']).first()
		faseItemSeleccionado = DBSession.query(Fase).filter_by(id = itemSeleccionado.fase_id).first()
		
		fasesProyecto = DBSession.query(Fase).filter_by(proyecto_id = faseItemSeleccionado.proyecto_id).order_by('orden').all()
		
		fasesDic = {}
		for fase in fasesProyecto:
			fasesDic[fase.id] = {'nombreFase': fase.nombre}
		
		items_visitados = {}
		items_relaciones = {}
		impacto = calcular_impacto(request.params['idItem'], items_visitados, items_relaciones, 'ATRAS')
		
		
		
		nombreImagen = generar_imagen_grafo(items_visitados, items_relaciones, fasesDic, request.params['idItem'])
		
		print '>>>este es el resultado del cálculo de impacto:' + str(impacto)
		
		
		
		responseView = Response()
		responseView.body = json.dumps(dict(success = True, nombreImagen = nombreImagen, impacto = impacto))
		responseView.content_type = 'application/json'
		return responseView	

	if dicParametros.get('operacion') == 'impactoTotal':	
		
		#necesitamos traer todas las fases ordenadas por orden
		itemSeleccionado = DBSession.query(Item).filter_by(id = request.params['idItem']).first()
		faseItemSeleccionado = DBSession.query(Fase).filter_by(id = itemSeleccionado.fase_id).first()
		
		fasesProyecto = DBSession.query(Fase).filter_by(proyecto_id = faseItemSeleccionado.proyecto_id).order_by('orden').all()
		
		fasesDic = {}
		for fase in fasesProyecto:
			fasesDic[fase.id] = {'nombreFase': fase.nombre}
		
		items_visitados = {}
		items_relaciones = {}
		impacto = calcular_impacto(request.params['idItem'], items_visitados, items_relaciones, 'TOTAL')
		
		'''print '>>>>>>>despues de salir ---> calcular_impacto'
		
		print '>>>>items visitados'
		print items_visitados
		
		print '>>>>relaciones'
		print items_relaciones'''
		
		nombreImagen = generar_imagen_grafo(items_visitados, items_relaciones, fasesDic, request.params['idItem'])
		
		print '>>>este es el resultado del cálculo de impacto:' + str(impacto)
		
		
		
		responseView = Response()
		responseView.body = json.dumps(dict(success = True, nombreImagen = nombreImagen, impacto = impacto))
		responseView.content_type = 'application/json'
		return responseView
	
	if dicParametros.get('operacion') == 'impactoAdelante':	
		
		#necesitamos traer todas las fases ordenadas por orden
		itemSeleccionado = DBSession.query(Item).filter_by(id = request.params['idItem']).first()
		faseItemSeleccionado = DBSession.query(Fase).filter_by(id = itemSeleccionado.fase_id).first()
		
		fasesProyecto = DBSession.query(Fase).filter_by(proyecto_id = faseItemSeleccionado.proyecto_id).order_by('orden').all()
		fasesDic = {}
		for fase in fasesProyecto:
			fasesDic[fase.id] = {'nombreFase': fase.nombre}
		
		items_visitados = {}
		items_relaciones = {}
		impacto = calcular_impacto(request.params['idItem'], items_visitados, items_relaciones, 'ADELANTE')
		
		nombreImagen = generar_imagen_grafo(items_visitados, items_relaciones, fasesDic, request.params['idItem'])
		
		print '>>>este es el resultado del cálculo de impacto:' + str(impacto)
		
		
		
		responseView = Response()
		responseView.body = json.dumps(dict(success = True, nombreImagen = nombreImagen, impacto = impacto))
		responseView.content_type = 'application/json'
		return responseView			
	
	if dicParametros.get('operacion') == 'descargarArchivo':	
		
		archivo = DBSession.query(ValoresArchivo).filter_by(item_id=request.params['idItem'], 
			nombreArchivo = request.params['nombreArchivo'], nombreAtributo = request.params['nombreAtributo'] , version_item = request.params['versionItem']).one()
		
		responseView = Response()
		responseView.body = archivo.valor
		responseView.content_type = 'application/force-download'
		responseView.content_length	= str(len(archivo.valor))
		responseView.content_transfer_encoding = 'binary'
		responseView.accept_ranges = 'bytes'
		responseView.content_disposition = 'attachment;filename='+ str(archivo.nombreArchivo) + ';'
		

		return responseView
	
	if dicParametros.get('operacion') == 'aprobarRevision':
		idItem = request.params['idItem']
	
		itemAprobado = session.query(Item).filter_by(id = idItem ).first()
		itemAprobado.flagRevisar = 0

		#si es que esta en una linea base vemos si podemos reestablecer su estado
		if itemAprobado.linea_base_id is not None:
			laLineaBase = session.query(Linea_Base).filter_by(id = itemAprobado.linea_base_id ).first()
			cambiar = True
			for item in laLineaBase.items:
				if item.flagRevisar == 1 or item.flagModificar == 1:
					cambiar = False
					break
			if cambiar:
				laLineaBase.estado = 'CERRADO'

		response = Response()
		response.body = json.dumps(dict(success = True))
		response.content_type = 'application/json'
		
		return response	
		
	if dicParametros.get('operacion') == 'rechazarRevision':
		idItem = request.params['idItem']
	
		itemAprobado = session.query(Item).filter_by(id = idItem ).first()
	
		itemAprobado.flagRevisar = 0
		itemAprobado.flagModificar = 1

		
		response = Response()
		response.body = json.dumps(dict(success = True))
		response.content_type = 'application/json'
		
		return response		


def calcular_impacto(itemID, items_visitados, items_relaciones, tipoImpacto):
	print "calcular_impacto:"
  
	#traemos todas las relaciones del item 
	relaciones = []
	
	antecesoresIDs = DBSession.query(RelacionA_S.antecesor).filter_by(sucesor = itemID).all()
	sucesoresIDs = DBSession.query(RelacionA_S.sucesor).filter_by(antecesor = itemID).all()
	
	hijosIDs = DBSession.query(RelacionP_H.hijo).filter_by(padre = itemID).all() 
	padresIDs = DBSession.query(RelacionP_H.padre).filter_by(hijo = itemID).all() 
	

	
	destinosIDs = antecesoresIDs + sucesoresIDs + hijosIDs + padresIDs


	item_recibido = DBSession.query(Item).filter_by(id = itemID).one()
	
	faseItem = DBSession.query(Fase).filter_by(id = item_recibido.fase_id).one() 
	items_visitados[item_recibido.id] = [item_recibido.id, item_recibido.fase_id, faseItem.orden, item_recibido.nombre, item_recibido.complejidad]
			

	suma_impacto = item_recibido.complejidad

	items_relaciones[int(itemID)] = []
	
	if tipoImpacto == 'ATRAS' or tipoImpacto == 'TOTAL':
	
		for destinoID in antecesoresIDs:
			
			item_destino = DBSession.query(Item).filter_by(id=destinoID[0]).one()
						
			if  item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1:
				items_relaciones[int(itemID)].append([item_destino.id, 'A'])
				#print items_relaciones[int(itemID)]
				
			if items_visitados.has_key(item_destino.id) == False and item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1 :
				
				
				suma_impacto = suma_impacto  + \
							   calcular_impacto(item_destino.id,items_visitados, items_relaciones, tipoImpacto)
						   
	if tipoImpacto == 'ADELANTE' or tipoImpacto == 'TOTAL':
	
		for destinoID in sucesoresIDs:
			
			item_destino = DBSession.query(Item).filter_by(id=destinoID[0]).one()
			
			if  item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1:
				items_relaciones[int(itemID)].append([item_destino.id, 'S'])
			
			if items_visitados.has_key(item_destino.id) == False and item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1 :
				
				
				suma_impacto = suma_impacto  + \
							   calcular_impacto(item_destino.id,items_visitados, items_relaciones, tipoImpacto)					   
	
	if tipoImpacto == 'ADELANTE' or tipoImpacto == 'TOTAL':	
		for destinoID in hijosIDs:
			
			item_destino = DBSession.query(Item).filter_by(id=destinoID[0]).one()
			
			if  item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1:
				items_relaciones[int(itemID)].append([item_destino.id, 'H' ])
			
			if items_visitados.has_key(item_destino.id) == False and item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1 :
				
				
				suma_impacto = suma_impacto  + \
							   calcular_impacto(item_destino.id,items_visitados, items_relaciones, tipoImpacto)	
							   
	if tipoImpacto == 'ATRAS' or tipoImpacto == 'TOTAL':	
		
		for destinoID in padresIDs:
			
			item_destino = DBSession.query(Item).filter_by(id=destinoID[0]).one()
			
			if  item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1:
				items_relaciones[int(itemID)].append([item_destino.id, 'P'])
		
			if items_visitados.has_key(item_destino.id) == False and item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1 :
				
				
				suma_impacto = suma_impacto  + \
							   calcular_impacto(item_destino.id,items_visitados, items_relaciones, tipoImpacto)						   				   
		
	return suma_impacto
	
	

def generar_imagen_grafo( items_visitados, items_relaciones, fasesDic, idItemOrigen):
	
	graph = pydot.Dot(graph_type='digraph')
	subGrafosDic = {}
	
	for fase_key in fasesDic:
		faseDic = fasesDic[fase_key]
		subGrafosDic[fase_key] = pydot.Cluster(str(fase_key),label = faseDic.get('nombreFase'), shape='rectangle', style='filled')
		graph.add_subgraph(subGrafosDic[fase_key])
	
	nodos_kw = {}
	
	
	for item_key in items_visitados.keys():
		datos_item = items_visitados[item_key]
		
		if str(datos_item[0]) == str(idItemOrigen):
			nodo = pydot.Node(datos_item[0], label = str(datos_item[3]) + '\n' + str(datos_item[4]), color = 'red' )	
		else:
			print '>>>datos_item[0]'
			print datos_item[0]
			
			print '>>>datos_item[3]'
			print datos_item[3]
			
			print 'datos_item[4]'
			print datos_item[4]
			
			nodo = pydot.Node(datos_item[0], label = str(datos_item[3]) + '\n' + str(datos_item[4]) )
		nodos_kw[item_key] = nodo
		
		subGrafosDic[datos_item[1]].add_node(nodos_kw[item_key])
		
	
	relacionesInsertadas = []
	for nodo_key in nodos_kw.keys():
	
		relaciones_id = items_relaciones[nodo_key]

		for relacion_id in relaciones_id:
			
			if relacion_id[1] == 'A' or relacion_id[1] == 'S':
				
				if relacion_id[1] == 'S' and (not relacionRepetidaEnDibujar(relacionesInsertadas, relacion_id[0], nodo_key)) :
					graph.add_edge(pydot.Edge(nodos_kw[relacion_id[0]], nodos_kw[nodo_key], constraint=False ))
					relacionesInsertadas.append([relacion_id[0], nodo_key])
				elif not relacionRepetidaEnDibujar(relacionesInsertadas, nodo_key, relacion_id[0]):
					graph.add_edge(pydot.Edge(nodos_kw[nodo_key], nodos_kw[relacion_id[0]], constraint=False ))
					relacionesInsertadas.append([nodo_key, relacion_id[0]])
			else:
				if  relacion_id[1] == 'P' and (not relacionRepetidaEnDibujar(relacionesInsertadas, relacion_id[0], nodo_key)) :
					graph.add_edge(pydot.Edge( nodos_kw[relacion_id[0]] ,nodos_kw[nodo_key]))
					relacionesInsertadas.append([relacion_id[0] ,nodo_key])
				elif not relacionRepetidaEnDibujar(relacionesInsertadas, nodo_key, relacion_id[0]):	
					graph.add_edge(pydot.Edge(nodos_kw[nodo_key], nodos_kw[relacion_id[0]] ))
					relacionesInsertadas.append([nodo_key, relacion_id[0]])
	
	
	#print '>>>relacionesInsertadas'
	#print relacionesInsertadas
	
	
	
		
	
	############################################DESARROLLO########################################
	nombreImagen = 'impacto/calculo_impacto' + str(time.time()) + '.png'
	graph.write_png( os.path.abspath("scp") + '/static/images/' + nombreImagen)
	graph.write_raw(os.path.abspath("scp") + '/static/images/impacto/example_cluster2.dot')
	############################################DESARROLLO########################################
	
	
	###########################################PRODUCCION#########################################
	'''nombreImagen = 'impacto/calculo_impacto' + str(time.time()) + '.png'
	graph.write_png( '/home/www/entorno/scp-is2012/scp/scp' + '/static/images/' + nombreImagen)
	graph.write_raw( '/home/www/entorno/scp-is2012/scp/scp' + '/static/images/impacto/example_cluster2.dot')'''
	###########################################PRODUCCION#########################################
	
	
	
	print "ejecute todo generar imangen.."
  
	return nombreImagen
	
	
def marcar_item_to_revision(itemID):
	
	antecesoresIDs = DBSession.query(RelacionA_S.antecesor).filter_by(sucesor = itemID).all()
	sucesoresIDs = DBSession.query(RelacionA_S.sucesor).filter_by(antecesor = itemID).all()
	
	hijosIDs = DBSession.query(RelacionP_H.hijo).filter_by(padre = itemID).all() 
	padresIDs = DBSession.query(RelacionP_H.padre).filter_by(hijo = itemID).all() 
	
	destinosIDs = antecesoresIDs + sucesoresIDs + hijosIDs + padresIDs
	
	for destinoID in destinosIDs:
		item_destino = DBSession.query(Item).filter_by(id=destinoID[0]).one()
		#marcamos el item para su revisión, si es una version actual y no borrada
		if item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1:		
			item_destino.flagRevisar = 1
			#si el item esta en una linea base cambiamos el estado del mismo
			if item_destino.linea_base_id is not None:
				laLineaBase = DBSession.query(Linea_Base).filter_by(id=item_destino.linea_base_id).one()
				laLineaBase.estado = 'REVISION'
			
		
def reproducir_relaciones_al_editar(itemID, nuevoItemID):
	
	session = DBSession()
	
	antecesoresIDs = DBSession.query(RelacionA_S.antecesor).filter_by(sucesor = itemID).all()
	sucesoresIDs = DBSession.query(RelacionA_S.sucesor).filter_by(antecesor = itemID).all()
	
	hijosIDs = DBSession.query(RelacionP_H.hijo).filter_by(padre = itemID).all() 
	padresIDs = DBSession.query(RelacionP_H.padre).filter_by(hijo = itemID).all() 
	

	item_recibido = DBSession.query(Item).filter_by(id = itemID).one()

	#reproducimos las relaciones con sus antecesores
	for destinoID in antecesoresIDs:
		
		item_destino = DBSession.query(Item).filter_by(id=destinoID[0]).one()
		
		#por las dudas
		if item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1:
			relacionAntecesor = RelacionA_S()
			relacionAntecesor.antecesor = item_destino.id
			relacionAntecesor.sucesor = nuevoItemID
			relacionAntecesor.duenho = nuevoItemID
			
			session.add(relacionAntecesor)
	   
		
	#reproducimos las relaciones con sus sucesores
	#comente porque no se puede dar el caso
	'''for destinoID in sucesoresIDs:
		
		item_destino = DBSession.query(Item).filter_by(id=destinoID[0]).one()

		#por las dudas
		if item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1:
			relacionSucesor = RelacionA_S()
			relacionSucesor.antecesor = nuevoItemID
			relacionSucesor.sucesor = item_destino.id
			relacionSucesor.duenho = item_destino.id
			
			session.add(relacionSucesor)'''					   
	
	
	#reproducimos las relaciones con sus hijos	
	#ahora si se puede dar el caso,  porque un item no Aprobado puede tener hijos
	for destinoID in hijosIDs:
		
		item_destino = DBSession.query(Item).filter_by(id=destinoID[0]).one()
		
		#por las dudas
		if item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1:
			relacionHijo = RelacionP_H()
			relacionHijo.padre = nuevoItemID
			relacionHijo.hijo = item_destino.id
			relacionHijo.duenho = item_destino.id
			
			session.add(relacionHijo)
		
		
							  
	#reproducimos la relaciones con sus Padres, en relidad solo puede tener un padre	
	for destinoID in padresIDs:
		
		item_destino = DBSession.query(Item).filter_by(id=destinoID[0]).one()
	
		#por las dudas
		if item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1:
			relacionPadre = RelacionP_H()
			relacionPadre.padre = item_destino.id
			relacionPadre.hijo = nuevoItemID
			relacionPadre.duenho = nuevoItemID
			
			session.add(relacionPadre)					   				   
	

def reproducir_relaciones_al_revertir(itemID, nuevoItemID):
	
	session = DBSession()
	
	antecesoresIDs = DBSession.query(RelacionA_S.antecesor).filter_by(sucesor = itemID).all()
	sucesoresIDs = DBSession.query(RelacionA_S.sucesor).filter_by(antecesor = itemID).all()
	
	hijosIDs = DBSession.query(RelacionP_H.hijo).filter_by(padre = itemID).all() 
	padresIDs = DBSession.query(RelacionP_H.padre).filter_by(hijo = itemID).all() 
	

	item_recibido = DBSession.query(Item).filter_by(id = itemID).one()

	
	#reproducimos las relaciones con sus antecesores
	for destinoID in antecesoresIDs:
		
		item_destino = DBSession.query(Item).filter_by(id=destinoID[0]).one()
		
		#caso en en el cual el destino no se borro, es la ultima version del item y se ecuentra en una linea base
		if item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1 and (item_destino.linea_base_id is not None):
			
			relacionAntecesor = RelacionA_S()
			relacionAntecesor.antecesor = item_destino.id
			relacionAntecesor.sucesor = nuevoItemID
			relacionAntecesor.duenho = nuevoItemID
			
			session.add(relacionAntecesor)
		
		#el item destino no fue borrado pero no es de la ultima version
		elif item_destino.flagBorrado == 0 and item_destino.flagUltimo == 0:
			item_destino_ultimo = DBSession.query(Item).filter_by(codigo = item_destino.codigo, flagUltimo = 1, fase_id = item_destino.fase_id).one()
			
			#si no fue borrado y se encuentra en una linea fase la ultima version regeneramos la relacion
			if item_destino_ultimo.flagBorrado == 0 and (item_destino_ultimo.linea_base_id is not None):
				relacionAntecesor = RelacionA_S()
				relacionAntecesor.antecesor = item_destino_ultimo.id
				relacionAntecesor.sucesor = nuevoItemID
				relacionAntecesor.duenho = nuevoItemID
				
				session.add(relacionAntecesor)  	
	   
		
	#reproducimos las relaciones con sus sucesores
	#comento porque no se puede dar el caso(si se esta editando no puede tener sucesores), aparte tre mal la ultima version del item
	'''for destinoID in sucesoresIDs:
		
		item_destino = DBSession.query(Item).filter_by(id=destinoID[0]).one()
		
		#caso en en el cual el destino no se borro y es la ultima version del item
		if item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1:
			relacionSucesor = RelacionA_S()
			relacionSucesor.antecesor = nuevoItemID
			relacionSucesor.sucesor = item_destino.id
			relacionSucesor.duenho = item_destino.id
			
			session.add(relacionSucesor)
		#el item destino no fue borrado pero no es de la ultima version
		elif item_destino.flagBorrado == 0 and item_destino.flagUltimo == 0:
			item_destino_ultimo = DBSession.query(Item).filter_by(codigo = item_destino.codigo, flagUltimo = 1).one()
			
			#si no fue borrado la ultima version regeneramos la relacion
			if item_destino_ultimo.flagBorrado == 0:
				relacionSucesor = RelacionA_S()
				relacionSucesor.antecesor = nuevoItemID
				relacionSucesor.sucesor = item_destino_ultimo.id
				relacionSucesor.duenho = item_destino_ultimo.id
				
				session.add(relacionSucesor)'''						   
	
	
	#reproducimos las relaciones con sus hijos
	#comento porque no se puede dar el caso, aparte tre mal la ultima version del item	
	#ahora si se puede dar el caso
	for destinoID in hijosIDs:
		
		item_destino = DBSession.query(Item).filter_by(id=destinoID[0]).one()
		
		#caso en el cual el destino no fue borrado y es la ultima version y la relacion no causa un ciclo
		if item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1 and comprobar_ciclos(item_destino.id, nuevoItemID) == False:
									
			relacionHijo = RelacionP_H()
			relacionHijo.padre = nuevoItemID
			relacionHijo.hijo = item_destino.id
			relacionHijo.duenho = item_destino.id
			
			session.add(relacionHijo)
		
		#caso en cual el item destino no fue borrado pero no es la ultima version
		elif item_destino.flagBorrado == 0 and item_destino.flagUltimo == 0:
			#debemos traer la ultima version del item destino 	
			item_destino_ultimo = DBSession.query(Item).filter_by(codigo = item_destino.codigo, flagUltimo = 1, fase_id = item_destino.fase_id).one()
			
			#vamos a crear la relacion solo si el item destino ultimo no fue borrado y la relacion no producira un ciclo
			if item_destino_ultimo.flagBorrado == 0 and comprobar_ciclos(item_destino_ultimo.id, nuevoItemID) == False:						
				relacionHijo = RelacionP_H()
				relacionHijo.padre = nuevoItemID
				relacionHijo.hijo = item_destino_ultimo.id
				relacionHijo.duenho = item_destino_ultimo.id
				session.add(relacionHijo)
							  
	#reproducimos la relaciones con sus Padres	
	for destinoID in padresIDs:
		
		print '>>>>>>>>>>>>>>entre en el for para reversionar padres'
		
		item_destino = DBSession.query(Item).filter_by(id=destinoID[0]).one()
		print '>>>>item_destino.flagBorrado'
		print item_destino.flagBorrado
		print '>>>>item_destino.flagUltimo'
		print item_destino.flagUltimo
		print '>>>>comprobar_ciclos(nuevoItemID, item_destino.id)'
		print comprobar_ciclos(nuevoItemID, item_destino.id)
		print '>>>>item_destino.estado'
		print item_destino.estado
	
		#caso en el cual el destino no fue borrado,es la ultima version, no causa un ciclo y se encuentra APROBADO o BLOQUEADO
		if item_destino.flagBorrado == 0 and item_destino.flagUltimo == 1 and comprobar_ciclos(nuevoItemID, item_destino.id) == False :#and (item_destino.estado ==  'APROBADO' or item_destino.estado ==  'BLOQUEADO'):
			
			relacionPadre = RelacionP_H()
			relacionPadre.padre = item_destino.id
			relacionPadre.hijo = nuevoItemID
			relacionPadre.duenho = nuevoItemID
			
			session.add(relacionPadre)
		#caso en cual el item destino no fue borrado pero no es la ultima version
		elif item_destino.flagBorrado == 0 and item_destino.flagUltimo == 0:
			#debemos traer la ultima version del item destino 	
			item_destino_ultimo = DBSession.query(Item).filter_by(codigo=item_destino.codigo, flagUltimo = 1, fase_id = item_destino.fase_id).one()
			
			#vamos a crear la relacion solo si el item destino ultimo no fue borrado, relacion no producira un ciclo y esta en estado APROBADO O BLOQUEADO
			if item_destino_ultimo.flagBorrado == 0 and comprobar_ciclos(nuevoItemID, item_destino_ultimo.id) == False:# '''and (item_destino_ultimo.estado ==  'APROBADO' or item_destino_ultimo.estado ==  'BLOQUEADO'):						
				relacionPadre = RelacionP_H()
				relacionPadre.padre = item_destino_ultimo.id
				relacionPadre.hijo = nuevoItemID
				relacionPadre.duenho = nuevoItemID
				
				session.add(relacionPadre)

def comprobar_ciclos(hijo, padre):
	
	session = DBSession()
	#print 'hijo'
	#print hijo
	#print 'padre'
	#print padre
	destinos_relaciones = session.query(RelacionP_H.padre).filter_by(hijo=padre).all()
	#print 'destinos_relaciones'
	#print destinos_relaciones
	retorno = False 
	
	for destino_relacion in destinos_relaciones:
		#print 'destino_relacion'
		#print destino_relacion[0]
		itemDestino = session.query(Item).filter_by(id=destino_relacion[0]).one()
		
		if itemDestino.flagUltimo == 1 and itemDestino.flagBorrado == 0:		
			if str(destino_relacion[0]) == str(hijo):
				print 'estoy en el caso base!!!'
				retorno = True
				break
			else:
				retorno = comprobar_ciclos(hijo, destino_relacion[0])
			
	return retorno


def puedeTabRelaciones(usuarioLogeado, faseID):
	
	#traemos el recurso
	session = DBSession()
	recurso = session.query(Recurso).filter_by( fase_id = faseID, tipo = 'F' ).first()
	asignacionesRecurso = []
	if recurso is not None:
		asignacionesRecurso = session.query(AsignacionRecurso).filter_by( recurso_id = recurso.id, usuario_id = usuarioLogeado.id ).all()
	
	#construimos el JSON que enviaremos
	respuesta = False
	done = False
	for asignacion in asignacionesRecurso:
		if done == True:
			break
		rolAsigncion = asignacion.rol											
		for permisoIter in rolAsigncion.permisos:
			#autorizacionesJson[permisoIter.nombre] = False		
			if permisoIter.nombre == 'VER_RELACION':
				respuesta = True
				done = True
				break
			
	return respuesta
		
def relacionRepetidaEnDibujar(relacionesInsertadas, item1, item2):
	respuesta = False
	for relacion in relacionesInsertadas:
		#print '>>>>comparando:' + str(item1) + '  yy ' + str(item2) + ' con ' + str(relacion[0])  + '  y  ' + str(relacion[1])
 		if (relacion[0] == item1 and relacion[1] == item2) or (relacion[0] == item2 and relacion[1] == item1):
			#print 'es igual!!!'
			respuesta = True
			break
		
	return respuesta
